module Decode( rst, clk, nxt_pc, inst, Rd_W, writedata, RegWrite_W,
               ext_i, Rs_val, Rt_val, target, 
               Rs_D, Rt_D, Rd_D,
               Jump, Branch, T, cntrl_D, cntrl_X, cntrl_M, nxt_pc_D);

 input rst, clk;
 input[15:0] nxt_pc;
 input[15:0] inst;
 input[15:0] writedata;
 input[2:0]  Rd_W;
 input       RegWrite_W;

 output[] cntrl_D;
 output[] cntrl_X;
 output[] cntrl_M;
 output[2:0] Rs_D;
 output[2:0] Rt_D;
 output[2:0] Rd_D; 
 output[15:0] ext_i;
 output[15:0] Rs_val;
 output[15:0] Rt_val;
 output[15:0] target;
 output[15:0] nxt_pc_D;
 
 output jump, Branch, T;

 immd_ext i_ext( .out(ext_i), .in(inst[7:0]), .s_z(s_z), .ExtMux(ExtMux) );
 
 cntrl_unit D_cntrl( .cntrl_in(inst[15:11]),
                     .cntrl_D(cntrl_D),
                     .cntrl_X(cntrl_X),
                     .cntrl_M(cntrl_M),
                     .s_z(s_Z),
                     .ExtMux(ExtMux),
                     .Jump(Jump),
                     .Branch(Branch) );
 
 hzrd_detect hd(.opcode(inst[15:11]), .Rs_val(Rs_val), .T(T));

 rf_bypass (  .read1data(Rs_val),
               .read2data(Rt_val),
               .err(),
               .clk(clk),
               .rst(rst), 
               .read1regsel(inst[10:8]),   //Rs
               .read2regsel(inst[7:5]),    //Rt
               .writeregsel(Rd_W),
               .writedata(writedata),
               .write(RegWrite_W)     );


 assign nxt_pc_D = nxt_pc;
 assign Rs_D = inst[10:8];
 assign Rt_D = inst[7:5];
 
 assign Rd_D = (RegDst == 2'b00)? inst[7:5] :
               (RegDst == 2'b01)? inst[4:2] :
               (RegDst == 2'b10)? inst[10:8] : 3'b111;   
 
 wire[15:0] target_t;

 assign target_t = (Jump)? {6{inst[10]}, inst[9:0]} : ext_i ;
 assign target = nxt_pc + target_t; 

 endmodule
 
